package svc

import (
	v1 "eag_arch_layout/api/baseArch/v1"
	"eag_arch_layout/internal/conf"
	"eag_arch_layout/internal/model/VO"
	"eag_arch_layout/internal/model/model"
	"eag_arch_layout/internal/utils"
	"github.com/go-kratos/kratos/v2/log"
	"github.com/jinzhu/copier"
	"golang.org/x/crypto/bcrypt"
)

// AccountRepo 账号数据仓库
type AccountRepo interface {
	// FindByLoginID 根据登录ID查询账号
	FindByLoginID(loginId string) (*model.VAccountInfo, error)
	// GetPwdHashByLoginID 根据登录ID查询密码哈希
	GetPwdHashByLoginID(loginId string) (string, error)
	// ChangePassword 修改密码
	ChangePassword(loginId []string, newPassword string) bool
	// ChkBeforeSave 检测保存前的数据(账号是否存在)
	ChkBeforeSave(po *model.SysAccount) bool
	// Save 保存
	Save(po *model.SysAccount) bool
	// Delete 删除
	Delete(idArray []string) error
	// GetPager 分页
	GetPager(para *VO.PageSearchModel) ([]*model.VAccountInfo, int64)
	// LockOrNot 锁定或解锁
	LockOrNot(id string) bool
}

// SystemRepo 系统数据仓库
type SystemRepo interface {
	// GetLastVersion 获取最新版本
	GetLastVersion() (*model.SysVersion, error)
}

// SystemSvc 系统服务层
type SystemSvc struct {
	ar  AccountRepo
	sr  SystemRepo
	log *log.Helper
}

func NewSystemSvc(repo1 AccountRepo, repo2 SystemRepo, logger log.Logger) *SystemSvc {
	return &SystemSvc{ar: repo1, sr: repo2, log: log.NewHelper(logger)}
}

// Login 登录
func (s *SystemSvc) Login(jwtConfig *conf.Jwt, para *v1.LoginRequest) (*v1.LoginReply, error) {
	po, err := s.ar.FindByLoginID(para.LoginID)
	if err != nil {
		return nil, err
	}
	err2 := bcrypt.CompareHashAndPassword([]byte(po.Password), []byte(para.LoginPwd))
	if err2 != nil {
		return &v1.LoginReply{
			Success: false,
			Error:   "账户或者密码错误",
		}, nil
	}
	result := v1.LoginReply_Data{}
	err3 := copier.Copy(&result, &po)
	if err3 != nil {
		return nil, err3
	}
	curUser := VO.CurUserInfo{}
	err4 := copier.Copy(&curUser, &po)
	if err4 != nil {
		return nil, err4
	}
	var mapClaims, _ = utils.StructToMap(&curUser)
	aToken, err5 := utils.GenerateToken(jwtConfig.Secret, mapClaims)
	if err5 != nil {
		return nil, err5
	}
	result.AToken = aToken
	return &v1.LoginReply{
		Success: true,
		Data:    &result,
	}, nil
}

// ChangePassword 修改密码
func (s *SystemSvc) ChangePassword(loginID string, para *v1.ChgPwdRequest) (bool, string, error) {
	pwdHash, err := s.ar.GetPwdHashByLoginID(loginID)
	if err != nil {
		return false, "", err
	}
	err2 := bcrypt.CompareHashAndPassword([]byte(pwdHash), []byte(para.OldPwd))
	if err2 == nil {
		flag := s.ar.ChangePassword([]string{loginID}, para.NewPwd)
		if flag {
			return false, "", nil
		}
		return true, "操作成功", nil
	}
	return false, "验证旧密码错误", nil
}

// GetLastVersion 获取最新版本
func (s *SystemSvc) GetLastVersion() (*v1.GetVersionReply, error) {
	v, err := s.sr.GetLastVersion()
	if err != nil {
		return nil, err
	}
	result := v1.GetVersionReply_Data{}
	err2 := copier.Copy(&result, &v)
	if err2 != nil {
		return nil, err2
	}
	return &v1.GetVersionReply{
		Success: true,
		Data:    &result,
	}, err
}
